package eerbaar.server.serializer.internal;

import java.io.StringReader;
import java.util.Iterator;
import java.util.Stack;

import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

import eerbaar.shared.tree.IAttributes;
import eerbaar.shared.tree.INode;
import eerbaar.shared.tree.NodeFactory;

public class ConvertToNode {

    public INode convert(String inXml) throws XMLStreamException {

        return privateConvert(inXml);
    }

    public INode privateConvert(String inXml) throws XMLStreamException {

        INode result = null;

        XMLEventReader reader = null;
        try {
            StringReader r = new StringReader(inXml);
            reader = XMLInputFactory.newInstance().createXMLEventReader(r);
        } catch (XMLStreamException e1) {
            e1.printStackTrace();
        } catch (FactoryConfigurationError e1) {
            e1.printStackTrace();
        }

        INode current = null;
        Stack<INode> stack = new Stack<INode>();

        while (reader.hasNext()) {
            XMLEvent event = reader.nextEvent();

            if (event.isStartElement()) {

                StartElement start = event.asStartElement();
                String key = start.getName().getLocalPart();
                INode node = NodeFactory.create(key);

                if (result == null) {
                    result = node;
                } else {
                    current.add(node);
                }

                current = node;
                stack.push(node);

                Iterator<?> i = start.getAttributes();
                while (i.hasNext()) {
                    Attribute a = (Attribute) i.next();

                    String aName = a.getName().getLocalPart();
                    String aValue = a.getValue();
                    IAttributes attributes = node.getAttributes();

                    int nValue = 0;
                    try {
                        nValue = Integer.parseInt(aValue);
                        attributes.set(Integer.class, aName, nValue);

                    } catch (NumberFormatException e) {

                        attributes.set(String.class, aName, aValue);
                    }
                }
            }

            if (event.isEndElement()) {
                stack.pop();
                current = null;
                if (stack.size() > 0) {
                    current = stack.peek();
                }
            }

        }

        return result;
    }

}
